/* 
 * File:   BoardController.cpp
 * Author: rc
 * 
 * Created on May 28, 2010, 1:14 PM
 */

#include <assert.h>
#include <iostream>
#include "headers/BoardController.h"

using namespace std;

BoardController::BoardController(Board* board) {
    assert(board != NULL);
    mBoard = board;
}

BoardController::BoardController() {    
    mBoard = new Board();
}

BoardController::BoardController(const BoardController& orig) {
}

BoardController::~BoardController() {
    //mBoard belongs to its controller. When the controller dies,
    //the board dies.    
    delete mBoard;
    detachAll();
}

/*
 * Color not allowed to be Board::NEUTRAL.
 * Index not allowed to be >=24 or <0.
 */
void BoardController::addPiece(Board::Colors color, int index) {
    assert(index <= 23);
    assert(index >= 0);
    assert(color != Board::NEUTRAL);
    mBoard->getTriangles()[index].first = color;
    mBoard->getTriangles()[index].second++;
    notify();
}


void BoardController::removePiece(int index) {
    assert(index >= 0);
    assert(index <= 23);
    if(mBoard->getTriangles()[index].second > 0) {
        mBoard->getTriangles()[index].second--;
        if(mBoard->getTriangles()[index].second == 0)
            mBoard->getTriangles()[index].first = Board::NEUTRAL;
    }
    notify();
}

Board::triangle* BoardController::getTriangleData(int index) {
    assert(index <= 23);
    assert(index >= 0);
    Board::triangle t;
    t.first = mBoard->getTriangles()[index].first;
    t.second = mBoard->getTriangles()[index].second;
    Board::triangle *tp;
    tp = &t;
    return tp;
}

/*
 * Moves a piece from the one triangle (src) to a
 * destination triangle (dest).
 * Parameters src and dest are the triangles. src and
 * dest >= 0. src cannot be the same triangle as dest.
 * A breach of this contract will cause an assertion error.
 */
void BoardController::movePiece(int src, int dest) {
    assert(src >= 0);
    assert(dest >= 0);
    assert(src != dest); //We can't move a piece to where it already is placed.

    //TODO: involve some rule-module here to make sure the move is valid.
    //the following assumes the move from src to dest was valid.
    Board::triangle *temptri = getTriangleData(src);
    removePiece(src);
    addPiece(temptri->first, temptri->second);
    notify(); //notifies the observers about the change.
}


